package com.src.xyzk.bluetooth.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.util.Log;

import com.src.xyzk.bluetooth.BluetoothDeviceListActivity;
import com.src.xyzk_personal.config.Common;
import com.src.xyzk_personal.config.Commonfunc;
import com.src.xyzk_personal.config.LogFile;

public class BluetoothAdapterService {
    //debug
    private static final String TAG = "BluetoothAdapterService";
    private static final boolean D = true;
    public final BluetoothAdapterService context = BluetoothAdapterService.this;
    private Handler m_handler = null;
    // 定义蓝牙UUID
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    //蓝牙adapter

    private static BluetoothAdapter m_adapter = null; // 蓝牙绑定操作类
    //蓝牙连接线程
    private ConnectThread m_connect_thread = null; // 蓝牙连接线程
    //private ConnectedThread m_connected_thread = null; // 蓝牙通讯监听线程
    private static BluetoothSocket m_socket = null;
    private static InputStream m_in_stream = null;
    private static OutputStream m_out_stream = null;
    //蓝牙状态对象
    public static BlueStateEvent m_blue_state = null;
    public boolean exit = false;
    private boolean m_record = false;  //LOG记录开关
    public LogFile m_log = LogFile.getInstance();	//日志对象


    //单例初始化
    private static BluetoothAdapterService m_bluetooth_service = null;

    //单例实现
    public synchronized static BluetoothAdapterService getInstance() {
        if (m_bluetooth_service == null) {
            m_bluetooth_service = new BluetoothAdapterService();
        }
        return m_bluetooth_service;
    }

    //类构造方法
    private BluetoothAdapterService() {
        m_adapter = BluetoothAdapter.getDefaultAdapter();
        m_blue_state = new BlueStateEvent(); //初始化蓝牙状态类
        exit = false;
    }

    public void Sethandler(Handler handler) {
        m_handler = handler;
    }

    public void SaveLogData(int mode, String data) {
        if (m_log != null) {
            m_log.PrintAppend(mode, data);
        }
    }

    /* ---------------------------接口方法(开始)-----------------------------------*/
    //参数为蓝牙MAC地址,长度为17位。格式为：“00:00:00:00：00:00”
    public boolean ConnectDevice(String deviceAddr) {
        //如果正在连接，则直接返回false
        if (m_blue_state.IsConnecting())
            return false;
        BluetoothDevice v_device = m_adapter.getRemoteDevice(deviceAddr);
        //设备初始化失败，也返回false
        if (v_device == null)
            return false;
        //启动连接线程
        m_connect_thread = new ConnectThread(v_device);
        m_connect_thread.start();
        //设置状态
        m_blue_state.SetConnecting();
        return true;
    }

    //停止蓝牙服务
    public void StopService() {
        if (D) Log.i(TAG, "结束蓝牙服务!");
        m_blue_state.SetListen();
        try {
            if (m_socket != null) {
                m_socket.close();
                m_socket = null;
            }
            if (m_in_stream != null) {
                m_in_stream.close();
                m_in_stream = null;
            }
            if (m_out_stream != null) {
                m_out_stream.close();
                m_out_stream = null;
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    void exit() {
        if (Common.Debug) Log.e(TAG, "执行了exit");
        exit = true;
    }

    //毫秒
    private void Sleep(int times) {
        try {
            Thread.sleep(times, 0);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //设置开始记录
    public void SetStartRecord(String vin) {
        char first = vin.charAt(0);
        if (first < 'A' || first > 'Z') return;
        //m_log = new LogFile(vin);
        if (m_log != null) {
            m_record = true;
            if (Common.Debug) Log.i(TAG, "开始记录日志!");
        } else {
            if (Common.Debug) Log.e(TAG, "创建记录日志失败!");
        }
    }

    public void PrintLog(String Pstr) {
        if (m_log != null) {
            m_log.PrintLog(Pstr);
        }
    }


    /* ---------------------------接口方法(结束)-----------------------------------*/

    /****************************蓝牙连接线程***************************************/
    private class ConnectThread extends Thread {
        private BluetoothDevice v_device = null;

        public ConnectThread(BluetoothDevice device) {
            v_device = device;
            try {
                m_socket = v_device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                Log.e(TAG, "create() Blue Socket failed", e);
            }
        }

        public void run() {
            Log.i(TAG, "BEGIN mConnectThread");
            setName("ConnectThread");
            //取消搜索
            m_adapter.cancelDiscovery();
            try {
                //建立连接....
                Log.i(TAG, "连接Socket");
                m_socket.connect();
                m_in_stream = m_socket.getInputStream();
                m_out_stream = m_socket.getOutputStream();
            } catch (IOException e) {
                ConnectThreadFailed();
                //关闭Socket
                try {
                    m_socket.close();
                } catch (IOException e2) {
                    Log.e(TAG, "unable to close() socket during connection failure", e2);
                }
                Log.i(TAG, "连接失败!");
                m_handler.obtainMessage(BluetoothDeviceListActivity.HAND_RECEIVE_CONNECT, 0, 0).sendToTarget();
                return;
            }
            Log.i(TAG, "连接成功!");

            m_blue_state.SetConnected();
            m_handler.obtainMessage(BluetoothDeviceListActivity.HAND_RECEIVE_CONNECT, 1, 0).sendToTarget();
        }
    }

    //连接失败处理方法
    private void ConnectThreadFailed() {
        m_blue_state.SetListen();
    }

    /****************************蓝牙通信方法(start)***************************************/
    //组合命令
    private int addData2Cmd(byte[] cmd, byte[] Pdata, int Plen, byte[] Pcmdbuf) {
        int cmdlen = 0;
        //这里组成发送的命令
        //先添加发送帧头
        Pcmdbuf[0] = 0x55;
        Pcmdbuf[1] = (byte) 0xAA;
        Pcmdbuf[2] = (byte) 0xC1;
        Pcmdbuf[3] = (byte) 0xB1;
        //计算长度
        cmdlen = 4 + 2 + 2 + Plen + 1;
        //填入长度字节
        Pcmdbuf[4] = (byte) ((cmdlen - 6) / 0x100);
        Pcmdbuf[5] = (byte) ((cmdlen - 6) % 0x100);
        //填入命令字
        Pcmdbuf[6] = cmd[0];
        Pcmdbuf[7] = cmd[1];
        //填入DATA
        for (int i = 0; i < Plen; i++) {
            Pcmdbuf[8 + i] = Pdata[i];
        }
        //计算校验
        Pcmdbuf[cmdlen - 1] = Commonfunc.CalcChechSum(Pcmdbuf, 4, cmdlen - 1);
        return cmdlen;
    }

    //发送数据，发一次收一次
    private int SendOneToOne(byte[] Psend, int Plen, byte[] Precv, int Psize, int maxtime) {
        int len = 0;
        if (m_out_stream == null || m_in_stream == null) return -1; //未连接
        try {
            if (m_in_stream.available() > 0)  //先清除数据
                m_in_stream.read(Precv, 0, m_in_stream.available());
            Sleep(1);
            m_out_stream.write(Psend, 0, Plen);
            Sleep(1);
            m_out_stream.flush();
            Sleep(5);
            //if(Common.Debug) Log.i(TAG,"Send:" + Commonfunc.bytesToHexString(Psend, 0,Plen));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (Common.Debug) Log.e(TAG, "Send异常");
        }
        len = Readdata(Precv, Psize, maxtime);
        return len;
    }

    //只收数据,保证收到完整帧
    private int Readdata(byte[] Precv, int Psize, int maxtime) {
        int len = 0;
        int all_len = 0;
        byte[] buf = new byte[256];
        if (m_out_stream == null || m_out_stream == null) {
            if (Common.Debug) Log.e(TAG, "Readdata exit 1");
            return -1; //未连接
        }
        try {
            long starttime = System.currentTimeMillis(); //获得起始时间
            long endtime = starttime;
            while (true) {
                Sleep(2);
                if (m_in_stream == null || exit == true) {
                    if (Common.Debug)
                        Log.e(TAG, "Readdata exit 2" + "dout=" + m_out_stream + ";din=" + m_in_stream + ";exit=" + exit);
                    len = -2;
                    break; //未连接
                }
                len = m_in_stream.available();
                if (len > 0) {
                    m_in_stream.read(Precv, all_len, len);
                    all_len += len;
                    //if(Common.Debug) Log.i(TAG,"Read:" + Commonfunc.bytesToHexString(Precv, 0,len));
                    if ((all_len == 9) && (Precv[5] == 0x03)) //收到下位机回复
                    {
                        //if(Common.Debug) Log.e(TAG,"Readdata exit 3");
                        break;
                    } else if (all_len > 9) //收到超过一帧,或者长帧
                    {
                        if (Precv[5] == 0x03) //表示是多帧
                        {
                            if ((all_len - 9) == ((Precv[14] & 0xFF) + 6)) {
                                //if(Common.Debug) Log.e(TAG,"Readdata exit 4");
                                break;
                            }
                        } else    //长帧
                        {
                            if (all_len == ((Precv[5] & 0xFF) + 6)) {
                                //if(Common.Debug) Log.e(TAG,"Readdata exit 5");
                                break;
                            }
                        }
                    }
                }
                endtime = System.currentTimeMillis();
                if (endtime > (starttime + maxtime)) //超时
                {
                    //if(Common.Debug) Log.i(TAG,"超时退出!");
                    len = -3;
                    break;
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (Common.Debug) Log.e(TAG, "接收异常");
        }
        return all_len;
    }

    //设置CAN线波特率
    public boolean SetCanBaud(long baud) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x06, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        if (m_log != null)
            m_log.PrintAppend(0, "SetBaud:" + baud);
        //获取波特率
        cmd[8] = (byte) ((baud / 0x10000) & 0xFF);
        cmd[9] = (byte) ((baud / 0x100) & 0xFF);
        cmd[10] = (byte) (baud & 0xFF);
        //计算校验
        cmd[11] = Commonfunc.CalcChechSum(cmd, 4, 11);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //设置P-CAN或B-CAN
    public boolean SetCanMode(int mode) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x04, 0x10, 0x09, 0x00, 0x00};
        byte[] Ans = new byte[128];
        //记录设置CAN
        if (m_log != null)
            m_log.PrintAppend(0, "SetCan:" + mode);
        //
        cmd[8] = (byte) (mode & 0xFF);
        //计算校验
        cmd[9] = Commonfunc.CalcChechSum(cmd, 4, 9);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }
    //设置CAN定制报文
    public boolean SetTimerCanCmd(byte Pid,int Pcanid,short Ptime,byte [] Pcmd)
    {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00};
        byte[] Ans = new byte[128];
        //记录设置CAN
        if (m_log != null)
            m_log.PrintAppend(0, "SetCanTimer:" + Ptime + "-Cmd:" + Commonfunc.bytesToHexString(Pcmd,0,8));
        //pid
        cmd[8] = Pid;
        //can id
        cmd[9] = (byte) (Pcanid / 0x100);
        cmd[10] = (byte) (Pcanid % 0x100);
        //timer
        cmd[11] = (byte) (Ptime / 0x100);
        cmd[12] = (byte) (Ptime % 0x100);
        //cmd
        System.arraycopy(Pcmd,0,cmd,13,8);
        //计算校验
        cmd[(cmd[5]&0xFF) + 5] = Commonfunc.CalcChechSum(cmd, 4, (cmd[5]&0xFF) + 5);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40))) {
            return true;
        }
        else {
            if (m_log != null)
                m_log.PrintAppend(0, "SetCanTimer: failed.");
            return false;
        }
    }

    //设置can过滤
    public boolean SetCanFilter(byte[] Pbuf, int num) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x08, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        //记录设置CAN ID
        if (m_log != null) {
            m_log.PrintAppend(0, "SetCanID:" + Commonfunc.bytesToHexString(Pbuf, 0, num * 2));
            m_log.setCanId(Pbuf); //设置canID
        }
        //
        cmd[8] = (byte) (num & 0xFF);
        for (int i = 0; i < num * 2; i++) {
            cmd[9 + i] = Pbuf[i];
        }
        //计算校验
        cmd[9 + num * 2] = Commonfunc.CalcChechSum(cmd, 4, 9 + num * 2);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //设置can自动回复
    public boolean SetCanAutoFrame(byte[] Pbuf, int Plen) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x0B, 0x10, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        for (int i = 0; i < Plen; i++) {
            cmd[8 + i] = Pbuf[i];
        }
        //计算校验
        cmd[8 + Plen] = Commonfunc.CalcChechSum(cmd, 4, 8 + Plen);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //设置标准帧中继数据
    public boolean SetStandCanAutoFrame(int Pid, byte[] Pbuf, int Plen) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x0D, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        cmd[8] = (byte) (Pid / 0x100);
        cmd[9] = (byte) (Pid & 0xFF);
        for (int i = 0; i < Plen; i++) {
            cmd[10 + i] = Pbuf[i];
        }
        //计算校验
        cmd[10 + Plen] = Commonfunc.CalcChechSum(cmd, 4, 10 + Plen);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40))) {
            if (m_log != null)
                m_log.PrintAppend(0, "SetAutoCmd:" + Pid + ":" + Commonfunc.bytesToHexString(Pbuf, 0, Plen));
            return true;
        } else
            return false;
    }

    //设置时序
    public boolean SetCommunTimer(int P1, int P2, int P3, int P4) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x09, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        cmd[8] = (byte) (P1 & 0xFF);
        cmd[9] = (byte) ((P2 / 0x100) & 0xFF);
        cmd[10] = (byte) (P2 & 0xFF);
        cmd[11] = (byte) ((P3 / 0x100) & 0xFF);
        cmd[12] = (byte) (P3 & 0xFF);
        cmd[13] = (byte) (P4 & 0xFF);
        //计算校验
        cmd[14] = Commonfunc.CalcChechSum(cmd, 4, 14);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //KWP波特率设置
    public boolean SetKwpBaud(long baud, int kwpmode) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x06, 0x10, 0x02, 0x00, 0x00, 0x02, 0x00};
        byte[] Ans = new byte[128];
        if (m_log != null)
            m_log.PrintAppend(0, "SetkwpBaud:" + baud);
        //获取波特率
        cmd[8] = (byte) ((baud / 0x100) & 0xFF);
        cmd[9] = (byte) (baud & 0xFF);
        //设置KWP模式
        cmd[10] = (byte) kwpmode;
        //计算校验
        cmd[11] = Commonfunc.CalcChechSum(cmd, 4, 11);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //获取序列号
    public boolean GetSerialNum(byte[] Serialnum, int Psize, byte[] softver) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x03, 0x20, 0x08, 0x00};
        byte[] Ans = new byte[128];
        //计算校验
        cmd[8] = Commonfunc.CalcChechSum(cmd, 4, 8);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40))) {
            System.arraycopy(Ans, 8, Serialnum, 0, 12);
            System.arraycopy(Ans, 22, softver, 0, 2);
            return true;
        } else
            return false;
    }

    //cmd使用can重发3次,发多帧收多帧
    public int CanSendAndRecvN2N(byte[] Send, int Plen, byte[] Recv, int Psize, int errorcode, int maxtime) {
        int error = 0;
        byte[] Readbuf = new byte[256];
        int i, iRet = 0;
        for (i = 0; i < Common.cmd_freq; i++) {
            iRet = CanSendMore2More(Send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= Common.cmd_freq) return 5001; //无响应
        if ((Readbuf[1] & 0xFF) == ((Send[1] + 0x40) & 0xFF)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        if (iRet > 0x200 || iRet < 1) return error;
        System.arraycopy(Readbuf, 0, Recv, 0, iRet);
        return error;
    }

    public int CanSendAndRecvO2O(byte[] Send, int Plen, byte[] Recv, int Psize, int errorcode, int maxtime) {
        int error = 0;
        byte[] Readbuf = new byte[256];
        int i, iRet = 0;
        for (i = 0; i < Common.cmd_freq; i++) {
            iRet = CanSendOne2One(Send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= Common.cmd_freq) return 5001; //无响应
        if (Readbuf[1] == (Send[1] + 0x40)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, Recv, 0, iRet);
        return error;
    }

    public int CanOne2OneUDS(int Preq, int Pres, byte[] Send, int Plen, byte[] Recv, int Perror, int Pmaxtime, int Pfreq) {
        int error = 0;
        int i;
        for (i = 0; i < Pfreq; i++) {
            error = CanOne2OneUDS(Preq, Pres, Send, Plen, Recv, Pmaxtime);
            if ((error > 0) && (((Send[1] & 0xFF) + 0x40) == (Recv[1] & 0xFF))) break;
            else if (error > 0) {
                int v_check = Send[1] & 0xFF;
                if (Plen > 0x100)  //超长
                    v_check = Send[2] & 0xFF;
                if ((v_check + 0x40) == (Recv[1] & 0xFF))
                    break;
            } else if (error < 0) {
                error = 5002;
            }
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= Pfreq)
            error = 5001; //无响应
        return error;
    }

    private int CanOne2OneUDS(int Preq, int Pres, byte[] send, int Plen, byte[] recv, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x30};
        byte [] cmdlink = {0x02,0x3E, (byte) 0x80};
        int framenum = 0;
        if (Plen > 20) {
            Sleep(1);
        }
        if (Plen <= 8) {
            framenum = 1;
        } else if (Plen <= 0x100) {
            framenum = (Plen + 6) / 7;
        } else
            framenum = (Plen + 5) / 7;
        byte[] data = new byte[10 + framenum * 8];
        Arrays.fill(data, (byte) 0);
        //记录发送的数据
        if (m_log != null) {
            String result = Commonfunc.bytesToHexString(send, 0, Plen);
            m_log.PrintAppend("Send", Preq, result);
        }
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //send id
        data[2] = (byte) (Preq / 0x100);
        data[3] = (byte) (Preq % 0x100);
        //recv id
        data[4] = (byte) (Pres / 0x100);
        data[5] = (byte) (Pres % 0x100);
        //特征报文
        data[6] = 0;
        data[7] = 0;
        //添加发送命令的帧数以及帧内容
        data[8] = (byte) (framenum / 0x100);
        data[9] = (byte) (framenum % 0x100);
        //添加内容
        int k = 0;
        if (Plen <= 0x100) //1位长度
        {
            if (Plen <= 8) {
                System.arraycopy(send, 0, data, 10, Plen);
            } else {
                //第一帧
                data[10] = 0x10;
                System.arraycopy(send, 0, data, 11, 7);
                for (k = 1; k < framenum - 1; k++) {
                    data[10 + k * 8] = (byte) (0x20 + k % 0x10);
                    System.arraycopy(send, k * 7, data, 11 + k * 8, 7);
                }
                //last
                k = (framenum - 1);
                data[10 + k * 8] = (byte) (0x20 + k % 0x10);
                int v_lastlen = Plen % 7;
                if (v_lastlen == 0)
                    v_lastlen = 7;
                System.arraycopy(send, k * 7, data, 11 + k * 8, v_lastlen);
            }
        } else {
            //第一帧
            data[10] = (byte) (0x10 + send[0]);
            System.arraycopy(send, 1, data, 11, 7);
            for (k = 1; k < framenum - 1; k++) {
                data[10 + k * 8] = (byte) (0x20 + k % 0x10);
                System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, 7);
            }
            //last
            k = (framenum - 1);
            data[10 + k * 8] = (byte) (0x20 + k % 0x10);
            int v_lastlen = (Plen - 1) % 7;
            if (v_lastlen == 0)
                v_lastlen = 7;
            System.arraycopy(send, 1 + k * 7, data, 11 + k * 8, v_lastlen);
        }

        //组合成命令
        byte[] Sendbuf = new byte[9 + data.length];
        int Sendlen = addData2Cmd(cmd, data, data.length, Sendbuf);

        //发送
        byte[] Readbuf = new byte[512];
        int iRet = SendOneToOneNew(Sendbuf, Sendlen, Readbuf, Readbuf.length, maxtime);
        if (iRet != 9) //nok
        {
            if (iRet >= 0) //
                iRet = -5;
            return iRet;
        }
        //接收数据
        while (true) {
            iRet = ReaddataComplete(Readbuf, Readbuf.length, maxtime + 500);
            if (iRet > 9) //ok
            {
                if ((Readbuf[5] == 0x0D) && (Readbuf[10] == 0x03) && (Readbuf[11] == 0x7F) && (Readbuf[13] == 0x78)) //wait
                {
                    if (m_log != null) {
                        m_log.PrintAppend("Recv", Pres, Commonfunc.bytesToHexString(Readbuf, 10, 14));
                    }
                    //if(maxtime > 10000)
                    //    CanSendOneOnly(0x7DF,cmdlink,3);
                    Sleep(10);
                    continue;
                } else //拷贝数据
                {
                    //拆开CAN包重组CAN数据
                    if ((Readbuf[8] & 0xFF) > 20) break;
                    if (Readbuf[8] == 1) //单帧
                    {
                        iRet = Readbuf[10] + 1;
                        for (int i = 0; i < iRet; i++)
                            recv[i] = Readbuf[10 + i];
                    } else if (Readbuf[8] > 1) //多帧
                    {
                        iRet = ((Readbuf[10] & 0x0F) << 8) + (Readbuf[11] & 0xFF) + 1;
                        for (int i = 0; i < Readbuf[8]; i++) {
                            System.arraycopy(Readbuf, 9 + i * 9 + 2, recv, i * 7, 7);
                        }
                    }
                    break;
                }
            } else if (iRet == 9 && Readbuf[6] == 0x6F && Readbuf[7] == 0x02) //timeout
            {
                iRet = -2;
                break;
            } else
                break;
        }

        //记录接收的数据
        if (m_log != null) {
            if (iRet > 0)
                m_log.PrintAppend("Recv", Pres, Commonfunc.bytesToHexString(recv, 0, iRet));
            else {
                if (iRet == -1)
                    m_log.PrintAppend(0, "Connect Lost!");
                else if (iRet == -2) {
                    m_log.PrintAppend(0, "Time out!");
                    iRet = 0;
                } else if (iRet == -3)
                    m_log.PrintAppend(0, "IOException!");
                else if (iRet == -4) {
                    m_log.PrintAppend(0, "Check failed!");
                    iRet = 0;
                } else if (iRet == -5)
                    m_log.PrintAppend(0, "Box error!");
                else
                    m_log.PrintAppend(0, "Else error!");
            }
        }
        return iRet;
    }

    private int SendOneToOneNew(byte[] Psend, int Plen, byte[] Precv, int Psize, int maxtime) {
        int len = 0;
        if (m_out_stream == null || m_in_stream == null) return -1; //未连接
        try {
            if (m_in_stream.available() > 0)  //先清除数据
                m_in_stream.skip(m_in_stream.available());
            m_out_stream.write(Psend, 0, Plen);
            m_out_stream.flush();
            Sleep(5);
            //if(Common.Debug) Log.i(TAG,"Send:" + Commonfunc.bytesToHexString(Psend, 0,Plen));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            //if(Common.Debug) Log.e(TAG,"Send异常");
        }
        len = ReaddataComplete(Precv, Psize, maxtime);
        return len;
    }

    private int ReaddataComplete(byte[] Precv, int Psize, int maxtime) {
        int readlen = 0;
        int all_len = 0;
        int datalen = 0;
        if (m_out_stream == null || m_out_stream == null) {
            if (Common.Debug) Log.e(TAG, "Readdata exit 1");
            return -1; //断线
        }
        try {
            long starttime = System.currentTimeMillis(); //获得起始时间
            long endtime = starttime;
            while (true) {
                Sleep(2);
                if (m_out_stream == null || m_in_stream == null || exit == true) {
                    //if(Common.Debug) Log.e(TAG,"Readdata exit 2" + "dout=" + m_out_stream + ";din=" + m_in_stream + ";exit=" + exit);
                    break; //未连接
                }
                readlen = m_in_stream.available();
                if ((readlen + all_len) >= 9) {
                    if (datalen == 0) //开始
                    {
                        m_in_stream.read(Precv, 0, 6);
                        all_len += 6;
                        if (((Precv[0] & 0xFF) == 0x55) && ((Precv[1] & 0xFF) == 0xAA))  //得到头
                        {
                            datalen = ((Precv[4] & 0xFF) << 8) + (Precv[5] & 0xFF);
                            if (datalen <= (readlen - 6)) //有完整数据,取数据返回
                            {
                                readlen = m_in_stream.read(Precv, all_len, datalen);
                                if (readlen == datalen) //ok返回
                                {
                                    all_len += datalen;
                                    break;
                                } else //清空
                                {
                                    all_len = 0;
                                    datalen = 0;
                                }
                            } else //无完整数据
                            {
                                if (datalen < 3) //error,或者无效数据
                                {
                                    all_len = 0;
                                    datalen = 0;
                                }
                            }
                        } else //无效数据
                        {
                            all_len = 0;
                            datalen = 0;
                        }
                    } else {
                        if (readlen >= datalen) //数据全了
                        {
                            readlen = m_in_stream.read(Precv, all_len, datalen);
                            if (readlen == datalen) //ok返回
                            {
                                all_len += datalen;
                                break;
                            } else //清空
                            {
                                all_len = 0;
                                datalen = 0;
                            }
                        }
                    }
                }
                endtime = System.currentTimeMillis();
                if (endtime > (starttime + maxtime)) //超时
                {
                    if (Common.Debug) Log.i(TAG, "超时退出!");
                    all_len = -2; //超时
                    break;
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            all_len = -3; //IO异常
            if (Common.Debug) Log.e(TAG, "接收异常");
        }
        //计算校验
        if (Precv[all_len - 1] != Commonfunc.CalcChechSum(Precv, 4, all_len - 1)) //nok
            all_len = -4; //校验失败
        return all_len;
    }

    //CAN发一帧收一帧，不判断返回值
    public int CanSendAndRecvO2O_Spec(byte[] Send, int Plen, byte[] Recv, int Psize, int errorcode, int maxtime) {
        int error = 0;
        byte[] Readbuf = new byte[256];
        int i, iRet = 0;
        for (i = 0; i < Common.cmd_freq; i++) {
            iRet = CanSendOne2One(Send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= Common.cmd_freq) return 5001; //无响应
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, Recv, 0, iRet);
        return error;
    }

    //cmd使用can重发3次,发多帧收多帧
    public int CanSendAndRecvN2N_LongTime(byte[] Send, int Plen, byte[] Recv, int Psize, int errorcode, int maxtime) {
        int error = 0;
        byte[] Readbuf = new byte[256];
        int i, iRet = 0;
        for (i = 0; i < Common.cmd_freq; i++) {
            iRet = CanSendMore2More_LongTime(Send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= Common.cmd_freq) return 5001; //无响应
        if (Readbuf[1] == (Send[1] + 0x40)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, Recv, 0, iRet);
        return error;
    }

    //cmd CAN 发多帧收多帧
    private int CanSendMore2More(byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x31};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null) {
            String result = Commonfunc.bytesToHexString(send, 0, Plen);
            m_log.PrintAppend(1, result);
        }
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //添加发送命令的帧数以及帧内容
        int framenum = 0;
        if (Plen <= 8) //单帧
        {
            framenum = 1;
            //添加一帧数据
            for (int i = 0; i < Plen; i++) {
                data[3 + i] = send[i];
            }
        } else    //多帧
        {
            framenum = (Plen + 6) / 7;
            if (framenum > 15) //越界
            {
                return 0;
            }
            for (int i = 0; i < framenum - 1; i++) {
                //添加帧头
                if (i == 0)
                    data[3 + i * 8] = 0x10;
                else
                    data[3 + i * 8] = (byte) (0x20 + i % 0x10);
                //添加内容
                for (int j = 0; j < 7; j++) {
                    data[3 + i * 8 + 1 + j] = send[i * 7 + j];
                }
            }
            //复制最后一帧
            //帧头
            data[3 + (framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
            int lastlen = Plen % 7;
            if (lastlen == 0) lastlen = 7;
            for (int j = 0; j < lastlen; j++) {
                data[3 + (framenum - 1) * 8 + 1 + j] = send[(framenum - 1) * 7 + j];
            }
        }
        //获取帧数
        data[2] = (byte) framenum;
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开CAN包重组CAN数据
                        if (Readbuf[8] == 1) //单帧
                        {
                            iRet = Readbuf[10] + 1;
                            for (int i = 0; i < iRet; i++)
                                recv[i] = Readbuf[10 + i];
                        } else if (Readbuf[8] > 1) //多帧
                        {
                            iRet = Readbuf[11] + 1;
                            int j;
                            for (int i = 0; i < Readbuf[8]; i++) {
                                for (j = 0; j < 7; j++) {
                                    recv[i * 7 + j] = Readbuf[9 + i * 9 + 2 + j];
                                }
                            }
                        }

                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开CAN包重组CAN数据
                if (Readbuf[17] == 1) //单帧
                {
                    iRet = Readbuf[19] + 1;
                    for (int i = 0; i < iRet; i++)
                        recv[i] = Readbuf[19 + i];
                } else if (Readbuf[17] > 1) //多帧
                {
                    iRet = Readbuf[20] + 1;
                    int j;
                    for (int i = 0; i < Readbuf[17]; i++) {
                        for (j = 0; j < 7; j++) {
                            recv[i * 7 + j] = Readbuf[18 + i * 9 + 2 + j];
                        }
                    }
                }
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0) {
            String result = Commonfunc.bytesToHexString(recv, 0, iRet);
            m_log.PrintAppend(2, result);
        }
        return iRet;
    }

    //cmd CAN 发多帧收多帧刷写
    private int CanSendMore2More_long(byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x33};
        byte[] data = new byte[5120];
        //记录发送的数据
        if (m_log != null) {
            String result = Commonfunc.bytesToHexString(send, 0, Plen);
            m_log.PrintAppend(1, result);
        }
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //添加发送命令的帧数以及帧内容
        int framenum = 0;
        if (Plen <= 8) //单帧
        {
            framenum = 1;
            //添加一帧数据
            for (int i = 0; i < Plen; i++) {
                data[3 + i] = send[i];
            }
        } else    //多帧
        {
            framenum = (Plen + 6) / 7;
            if (framenum > 600) //越界
            {
                return 0;
            }
            for (int i = 0; i < framenum - 1; i++) {
                //添加帧头
                if (i == 0)
                    data[4 + i * 8] = 0x10;
                else
                    data[4 + i * 8] = (byte) (0x20 + i % 0x10);
                //添加内容
                for (int j = 0; j < 7; j++) {
                    data[4 + i * 8 + 1 + j] = send[i * 7 + j];
                }
            }
            //复制最后一帧
            //帧头
            data[4 + (framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
            int lastlen = Plen % 7;
            if (lastlen == 0) lastlen = 7;
            for (int j = 0; j < lastlen; j++) {
                data[4 + (framenum - 1) * 8 + 1 + j] = send[(framenum - 1) * 7 + j];
            }
        }
        //获取帧数
        data[2] = (byte) (framenum / 0x100);
        data[3] = (byte) (framenum % 0x100);
        //组合成命令
        byte[] Sendbuf = new byte[5120];
        int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 4, Sendbuf);
        if (Common.Debug) {
            //Log.i(TAG,"Sed:" + Commonfunc.bytesToHexString(send, 0,Plen));
            //Log.i(TAG,"Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0,Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开CAN包重组CAN数据
                        if (Readbuf[8] == 1) //单帧
                        {
                            iRet = Readbuf[10] + 1;
                            for (int i = 0; i < iRet; i++)
                                recv[i] = Readbuf[10 + i];
                        } else if (Readbuf[8] > 1) //多帧
                        {
                            iRet = Readbuf[11] + 1;
                            int j;
                            for (int i = 0; i < Readbuf[8]; i++) {
                                for (j = 0; j < 7; j++) {
                                    recv[i * 7 + j] = Readbuf[9 + i * 9 + 2 + j];
                                }
                            }
                        }

                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开CAN包重组CAN数据
                if (Readbuf[17] == 1) //单帧
                {
                    iRet = Readbuf[19] + 1;
                    for (int i = 0; i < iRet; i++)
                        recv[i] = Readbuf[19 + i];
                } else if (Readbuf[17] > 1) //多帧
                {
                    iRet = Readbuf[20] + 1;
                    int j;
                    for (int i = 0; i < Readbuf[17]; i++) {
                        for (j = 0; j < 7; j++) {
                            recv[i * 7 + j] = Readbuf[18 + i * 9 + 2 + j];
                        }
                    }
                }
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0) {
            String result = Commonfunc.bytesToHexString(recv, 0, iRet);
            m_log.PrintAppend(2, result);
        }
        return iRet;
    }

    //CAN发一帧收一帧
    private int CanSendOne2One(byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x32};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null) {
            String result = Commonfunc.bytesToHexString(send, 0, Plen);
            m_log.PrintAppend(1, result);
        }
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //添加发送命令的帧数以及帧内容
        int framenum = 0;
        if (Plen <= 8) //单帧
        {
            framenum = 1;
            //添加一帧数据
            for (int i = 0; i < Plen; i++) {
                data[3 + i] = send[i];
            }
        } else    //多帧
        {
            framenum = (Plen + 6) / 7;
            if (framenum > 15) //越界
            {
                return 0;
            }
            for (int i = 0; i < framenum - 1; i++) {
                //添加帧头
                if (i == 0)
                    data[3 + i * 8] = 0x10;
                else
                    data[3 + i * 8] = (byte) (0x20 + i % 0x10);
                //添加内容
                for (int j = 0; j < 7; j++) {
                    data[3 + i * 8 + 1 + j] = send[i * 7 + j];
                }
            }
            //复制最后一帧
            //帧头
            data[3 + (framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
            int lastlen = Plen % 7;
            if (lastlen == 0) lastlen = 7;
            for (int j = 0; j < lastlen; j++) {
                data[3 + (framenum - 1) * 8 + 1 + j] = send[(framenum - 1) * 7 + j];
            }
        }
        //获取帧数
        data[2] = (byte) framenum;
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, maxtime + 800);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开CAN包重组CAN数据
                        if (Readbuf[8] == 1) //单帧
                        {
                            iRet = 8;
                            for (int i = 0; i < 8; i++)
                                recv[i] = Readbuf[10 + i];
                        } else if (Readbuf[8] > 1) //多帧
                        {
                        }

                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开CAN包重组CAN数据
                if (Readbuf[17] == 1) //单帧
                {
                    iRet = 8;
                    for (int i = 0; i < 8; i++)
                        recv[i] = Readbuf[19 + i];
                } else if (Readbuf[17] > 1) //多帧
                {
                }
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0) {
            m_log.PrintAppend(2, Commonfunc.bytesToHexString(recv, 0, iRet));
        }
        return iRet;
    }

    //cmd CAN 发多帧收多帧,特殊处理超长时间收数据
    private int CanSendMore2More_LongTime(byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x31};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null) {
            m_log.PrintAppend(1, Commonfunc.bytesToHexString(send, 0, Plen));
        }
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //添加发送命令的帧数以及帧内容
        int framenum = 0;
        if (Plen <= 8) //单帧
        {
            framenum = 1;
            //添加一帧数据
            for (int i = 0; i < Plen; i++) {
                data[3 + i] = send[i];
            }
        } else    //多帧
        {
            framenum = (Plen + 6) / 7;
            if (framenum > 15) //越界
            {
                return 0;
            }
            for (int i = 0; i < framenum - 1; i++) {
                //添加帧头
                if (i == 0)
                    data[3 + i * 8] = 0x10;
                else
                    data[3 + i * 8] = (byte) (0x20 + i % 0x10);
                //添加内容
                for (int j = 0; j < 7; j++) {
                    data[3 + i * 8 + 1 + j] = send[i * 7 + j];
                }
            }
            //复制最后一帧
            //帧头
            data[3 + (framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
            int lastlen = Plen % 7;
            if (lastlen == 0) lastlen = 7;
            for (int j = 0; j < lastlen; j++) {
                data[3 + (framenum - 1) * 8 + 1 + j] = send[(framenum - 1) * 7 + j];
            }
        }
        //获取帧数
        data[2] = (byte) framenum;
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, maxtime + 20000);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开CAN包重组CAN数据
                        if (Readbuf[8] == 1) //单帧
                        {
                            iRet = Readbuf[10] + 1;
                            for (int i = 0; i < iRet; i++)
                                recv[i] = Readbuf[10 + i];
                        } else if (Readbuf[8] > 1) //多帧
                        {
                            iRet = Readbuf[11] + 1;
                            int j;
                            for (int i = 0; i < Readbuf[8]; i++) {
                                for (j = 0; j < 7; j++) {
                                    recv[i * 7 + j] = Readbuf[9 + i * 9 + 2 + j];
                                }
                            }
                        }

                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开CAN包重组CAN数据
                if (Readbuf[17] == 1) //单帧
                {
                    iRet = Readbuf[19] + 1;
                    for (int i = 0; i < iRet; i++)
                        recv[i] = Readbuf[19 + i];
                } else if (Readbuf[17] > 1) //多帧
                {
                    iRet = Readbuf[20] + 1;
                    int j;
                    for (int i = 0; i < Readbuf[17]; i++) {
                        for (j = 0; j < 7; j++) {
                            recv[i * 7 + j] = Readbuf[18 + i * 9 + 2 + j];
                        }
                    }
                }
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0) {
            String result = Commonfunc.bytesToHexString(recv, 0, iRet);
            m_log.PrintAppend(2, result);
        }
        return iRet;
    }

    //CAN只发一帧数据,返回1成功
    public int CanSendOneOnly(int SendId, byte[] send, int Plen) {
        byte[] cmd = new byte[]{0x11, 0x39};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null) {
            String result = Commonfunc.bytesToHexString(send, 0, Plen);
            m_log.PrintAppend("Send", SendId, result);
        }
        data[0] = 0x01;  //can模式
        data[1] = 0x00;
        data[2] = 0x00;
        data[3] = (byte) (SendId / 0x100);
        data[4] = (byte) (SendId % 0x100);
        //添加发送命令的帧数以及帧内容
        System.arraycopy(send, 0, data, 5, Plen);
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, 13, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            iRet = 1;
        } else
            iRet = 0;
        return iRet;
    }

    //KWP快速初始化
    public int KwpFastConnect(int baud, int kwpmode, byte[] send, int Plen, byte[] recv, int Psize, int maxtime, int testtimes, int errorcode) {
        int error = 0;
        int i, iRet = 0;
        //设置波特率
        for (i = 0; i < Common.cmd_freq; i++) {
            if (SetKwpBaud(baud, kwpmode) == true)
                break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        Sleep(Common.waittime);
        if (i == Common.cmd_freq) return 5001;
        //发送数据
        //先计算校验
        send[Plen - 1] = Commonfunc.CalcChechSum(send, 0, Plen - 1);
        byte[] Readbuf = new byte[256];
        for (i = 0; i < testtimes; i++) {
            iRet = KwpFastInit((byte) 0x19, (byte) 0x19, send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= testtimes) return 5001;
        int r_Pos = 5;
        if ((Readbuf[2] & 0xFF) == 0x80) r_Pos++; //当收到0x80开头的
        int s_Pos = 3;
        if ((send[0] & 0xFF) == 0x80) s_Pos++;
        if (Readbuf[r_Pos] == (send[s_Pos] + 0x40)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, recv, 0, iRet);
        return error;
    }

    //KWP快速初始化
    private int KwpFastInit(byte Plow, byte Phih, byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x01};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null) {
            m_log.PrintAppend(1, Commonfunc.bytesToHexString(send, 0, Plen));
        }
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //拉低拉高时间
        data[2] = Plow;
        data[3] = Phih;
        //添加发送命令
        System.arraycopy(send, 0, data, 4, Plen);
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, Plen + 4, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, Common.cmdmaxtime);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开数据
                        recv[0] = 0x01;
                        recv[1] = (byte) iRet;
                        System.arraycopy(Readbuf, 8, recv, 2, iRet);
                        iRet += 2;
                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开数据
                recv[0] = 0x01;
                recv[1] = (byte) iRet;
                System.arraycopy(Readbuf, 17, recv, 2, iRet);
                iRet += 2;
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0) {
            m_log.PrintAppend(2, Commonfunc.bytesToHexString(recv, 0, iRet));
        }
        return iRet;
    }

    //KWP快速初始化
    public int KwpOneToOne(byte[] send, int Plen, byte[] recv, int Psize, int maxtime, int testtimes, int errorcode) {
        int error = 0;
        int i, iRet = 0;
        //发送数据
        //先计算校验
        send[Plen - 1] = Commonfunc.CalcChechSum(send, 0, Plen - 1);
        byte[] Readbuf = new byte[256];
        for (i = 0; i < testtimes; i++) {
            iRet = KwpSendOne2One(send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= testtimes) return 5001;
        int r_Pos = 5;
        if ((Readbuf[2] & 0xFF) == 0x80) r_Pos++; //当收到0x80开头的
        int s_Pos = 3;
        if ((send[0] & 0xFF) == 0x80) s_Pos++;
        if ((Readbuf[r_Pos] & 0xFF) == ((send[s_Pos] & 0xFF) + 0x40)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, recv, 0, iRet);
        return error;
    }

    //KWP快速初始化
    private int KwpSendOne2One(byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x02};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null) {
            m_log.PrintAppend(1, Commonfunc.bytesToHexString(send, 0, Plen));
        }
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //添加发送命令
        System.arraycopy(send, 0, data, 2, Plen);
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, Plen + 2, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[256];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, Common.cmdmaxtime);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开数据
                        recv[0] = 0x01;
                        recv[1] = (byte) iRet;
                        System.arraycopy(Readbuf, 8, recv, 2, iRet);
                        iRet += 2;
                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开数据
                recv[0] = 0x01;
                recv[1] = (byte) iRet;
                System.arraycopy(Readbuf, 17, recv, 2, iRet);
                iRet += 2;
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0) {
            String result = Commonfunc.bytesToHexString(recv, 0, iRet);
            m_log.PrintAppend(2, result);
        }
        return iRet;
    }


    /****************************蓝牙通信方法（结束）***************************************/

    public class BlueStateEvent {
        //预定义的几种蓝牙状态
        public static final int STATE_NONE = 0; // 无连接
        public static final int STATE_LISTEN = 1; // 监听状态
        public static final int STATE_CONNECTING = 2; // 正在连接...
        public static final int STATE_CONNECTED = 3; // 蓝牙已经连接.
        //蓝牙状态变量
        private int m_state = STATE_NONE;

        /**
         * 设置State状态
         */
        private void SetState(int state) {
            if (D)
                Log.d(TAG, "setState() " + "蓝牙State = " + state);
            m_state = state;
        }

        //设置蓝牙为监听状态
        public void SetListen() {
            SetState(STATE_LISTEN);
        }

        //设置为正在连接状态
        public void SetConnecting() {
            SetState(STATE_CONNECTING);
        }

        //设置为已经连接状态
        public void SetConnected() {
            SetState(STATE_CONNECTED);
        }

        //获取蓝牙状态
        public synchronized int GetBlueState() {
            return m_state;
        }

        //判断是否已经连接
        public boolean IsConnected() {
            if (m_state == STATE_CONNECTED)
                return true;
            else
                return false;
        }

        //判断是否正在连接
        public boolean IsConnecting() {
            if (m_state == STATE_CONNECTING)
                return true;
            else
                return false;
        }

        //判断是否连接中断
        public boolean IsConnectLost() {
            if (m_state == STATE_LISTEN || m_state == STATE_NONE)
                return true;
            else
                return false;
        }
    }
}
